package br.unirio.leilao.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import br.unirio.leilao.entity.Album;
import br.unirio.leilao.entity.OfertaVenda;
import br.unirio.leilao.entity.Usuario;

public class OfertaVendaDAO {
	
	private Connection connection;
	private static OfertaVendaDAO instance;

	/**
	 * abre conexao com o banco
	 */
	public OfertaVendaDAO() {
		this.connection = new ConnectionFactory().getConnection();
	}
	
	/**
	 * Retorna a instancia unica da classe
	 * @return
	 */
	public static OfertaVendaDAO getInstance()
	{
		if (instance == null)
			instance = new OfertaVendaDAO();
		
		return instance;
	}
	
	/**
	 * pega uma oferta de venda do banco
	 * @param idOferta
	 * @return
	 */
	public OfertaVenda getOferta(int idOferta) {
		
		try{
			OfertaVenda ofertaVenda = new OfertaVenda();
			PreparedStatement stmt = this.connection.prepareStatement("select * from ofertavenda where ID = ?");
			stmt.setInt(1, idOferta);
			ResultSet rs = stmt.executeQuery();

			if (rs.next()) {
								
				ofertaVenda.setId(rs.getInt("ID"));
				ofertaVenda.setAtivo(rs.getBoolean("Ativo"));
				ofertaVenda.setAlbum(new Album(rs.getInt("IDAlbum")));
				ofertaVenda.setUsuario(UsuarioDAO.getInstance().getUsuarioById(rs.getInt("IDUsuario")));
				ofertaVenda.setPrecoFinal(rs.getFloat("PrecoFinal"));
				ofertaVenda.setPrecoInicial(rs.getFloat("PrecoInicial"));
				ofertaVenda.setDataFim(rs.getDate("DataFim"));
				ofertaVenda.setDataInicio(rs.getDate("DataInicio"));
				ofertaVenda.setDescricao(rs.getString("Descricao"));

			}

			rs.close();
			stmt.close();

			return ofertaVenda;
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * retorna todas as ofertas de vendas ativas para um álbum
	 * @param idAlbum
	 * @return
	 */
	public List<OfertaVenda> getOfertasAtivas(int idAlbum) {
		
		try{
			List<OfertaVenda> ofertasVenda = new ArrayList<OfertaVenda>();
			PreparedStatement stmt = this.connection.prepareStatement("select * from ofertavenda where IDAlbum = ? and ativo = true;");
			stmt.setInt(1, idAlbum);
			ResultSet rs = stmt.executeQuery();

			while (rs.next()) {
				
				OfertaVenda ofertaVenda = new OfertaVenda();
				ofertaVenda.setId(rs.getInt("ID"));
				ofertaVenda.setAtivo(Boolean.TRUE);
				ofertaVenda.setAlbum(new Album(rs.getInt("IDAlbum")));
				ofertaVenda.setUsuario(new Usuario(rs.getInt("IDUsuario")));
				ofertaVenda.setPrecoFinal(rs.getFloat("PrecoFinal"));
				ofertaVenda.setPrecoInicial(rs.getFloat("PrecoInicial"));
				ofertaVenda.setDataFim(rs.getDate("DataFim"));
				ofertaVenda.setDataInicio(rs.getDate("DataInicio"));
				ofertaVenda.setDescricao(rs.getString("Descricao"));
				ofertasVenda.add(ofertaVenda);
			}
			
			if(ofertasVenda.size() == 0) {
				return null;
			}

			rs.close();
			stmt.close();

			return ofertasVenda;
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * retorna o numero todas as ofertas de vendas ativas para um álbum
	 * @param idAlbum
	 * @return
	 */
	public int getNumeroOfertasAtivas(int idAlbum) {
		
		try{
			List<OfertaVenda> ofertasVenda = new ArrayList<OfertaVenda>();
			PreparedStatement stmt = this.connection.prepareStatement("select * from ofertavenda where IDAlbum = ? and ativo = true;");
			stmt.setInt(1, idAlbum);
			ResultSet rs = stmt.executeQuery();

			while (rs.next()) {
				
				OfertaVenda ofertaVenda = new OfertaVenda();
				ofertaVenda.setId(rs.getInt("ID"));
				ofertaVenda.setAtivo(Boolean.TRUE);
				ofertaVenda.setAlbum(new Album(rs.getInt("IDAlbum")));
				ofertaVenda.setUsuario(new Usuario(rs.getInt("IDUsuario")));
				ofertaVenda.setPrecoFinal(rs.getFloat("PrecoFinal"));
				ofertaVenda.setPrecoInicial(rs.getFloat("PrecoInicial"));
				ofertaVenda.setDataFim(rs.getDate("DataFim"));
				ofertaVenda.setDataInicio(rs.getDate("DataInicio"));
				ofertaVenda.setDescricao(rs.getString("Descricao"));
				ofertasVenda.add(ofertaVenda);
			}

			rs.close();
			stmt.close();

			return ofertasVenda.size();
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * registra uma oferta de venda.
	 * @param oferta
	 */
	public void registraOfertaVenda(OfertaVenda oferta) {
		
		String sql = "INSERT INTO `ofertavenda`(`Ativo`,`IDUsuario`,`IDAlbum`,`Descricao`,`DataInicio`,`DataFim`,`PrecoInicial`,`PrecoFinal`)VALUES(?,?,?,?,?,?,?,?);";
		
		try {
			// prepared statement para inserir
			PreparedStatement stmt = connection.prepareStatement(sql);
			// seta os valores
			stmt.setBoolean(1, Boolean.TRUE);
			stmt.setInt(2, oferta.getUsuario().getId());
			stmt.setInt(3, oferta.getAlbum().getId());
			stmt.setString(4, oferta.getDescricao());
			Calendar stCal = Calendar.getInstance();
			java.util.Date utlDate = stCal.getTime();
			java.sql.Date sqlDate = new java.sql.Date(utlDate.getTime());;
			stmt.setDate(5, sqlDate);
			stmt.setDate(6, new java.sql.Date(oferta.getDataFim().getTime()));
			stmt.setFloat(7, oferta.getPrecoInicial());
			stmt.setFloat(8, oferta.getPrecoFinal());
			// executa
			stmt.execute();
			stmt.close();
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	
	}
	
	/**
	 * retorna o menor pre�o de um album
	 * @param idAlbum
	 * @return
	 */
	public String retornaMenorPrecoAlbum(int idAlbum) {
		try{
			String menorPreco = null;
			PreparedStatement stmt = this.connection.prepareStatement("SELECT min(PrecoInicial) as PrecoInicial FROM `ofertavenda` where IDAlbum = ?;");
			stmt.setInt(1, idAlbum);
			ResultSet rs = stmt.executeQuery();

			if (rs.next()) {
				menorPreco = String.valueOf(rs.getFloat("PrecoInicial"));
			} 
			if(menorPreco.equals("0.0")){
				menorPreco = "-";
			}

			rs.close();
			stmt.close();

			return menorPreco;
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * encerra uma oferta de venda.
	 * @param idOfertaVenda
	 */
	public void encerraOfertavenda(int idOfertaVenda) {
		
		String sql = "UPDATE `ofertavenda` SET `Ativo`=false WHERE ID=?;";
		
		try {
			// prepared statement para inserir
			PreparedStatement stmt = connection.prepareStatement(sql);
			// seta os valores
			stmt.setInt(1, idOfertaVenda);
			// executa
			stmt.execute();
			stmt.close();
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	
	/**
	 * se uma oferta de compra for feita, o preco inicial eh atualizado.
	 * @param idOfertaVenda
	 */
	public void atualizaPrecoInicialOfertavenda(int idOfertaVenda, float oferta) {
		
		String sql = "UPDATE `ofertavenda` SET `PrecoInicial`=? WHERE ID=?;";
		
		try {
			// prepared statement para inserir
			PreparedStatement stmt = connection.prepareStatement(sql);
			// seta os valores
			stmt.setFloat(1, oferta);
			stmt.setInt(2, idOfertaVenda);
			// executa
			stmt.execute();
			stmt.close();
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
}

